package com.webvihar.access2db.activities;

import java.util.ArrayList;
import java.util.List;

import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.Spinner;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;

import com.webvihar.access2db.R;
import com.webvihar.access2db.asynctasks.A2DbAsyncWebRequestTask;
import com.webvihar.access2db.builders.RunQueryBuilder;
import com.webvihar.access2db.builders.RunSelectQueryBuilder;
import com.webvihar.access2db.builders.RunShowQueryBuilder;
import com.webvihar.access2db.model.QueryResult;
import com.webvihar.access2db.model.SelectQueryResult;
import com.webvihar.access2db.model.ShowQueryResult;
import com.webvihar.access2db.model.Table;
import com.webvihar.access2db.model.TableDataItem;
import com.webvihar.access2db.model.TableRowItem;
import com.webvihar.access2db.restapi.A2DbRunQueryRequest;
import com.webvihar.access2db.restapi.A2DbRunSelectQueryRequest;
import com.webvihar.access2db.restapi.A2DbRunShowQueryRequest;
import com.webvihar.access2db.restapi.A2DbWebResult;
import com.webvihar.access2db.restapi.BaseA2DbQueryRequest;
import com.webvihar.access2db.restapi.IA2DbWebRequestDelegate;
import com.webvihar.access2db.utils.PreferencesManager;

public class QueryEditorActivity extends BaseActivity implements OnClickListener{
	
	private TextView titleTxt;
	private ImageButton titleActionButton;
	private TableLayout outputTable;
	private EditText query;
	private Button goBtn;
	private Spinner databaseSp;
	private Button consoleBtn;
	private Button tableBtn;
	private LinearLayout consoleView;
	private LinearLayout tableView;
	private Button clearBtn;

	private List<View> rows;
	private List<TableRowItem> tableRows;

	/** Called when the activity is first created. **/
	@Override 
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.query_editor);
		initUI();
		setTitleBar();
		setListeners();
		showConsoleTab();
	}
	
	@Override
	protected void onResume() {
		super.onResume();
		startDatabaseRequestProcess();
	}

	public void setTitleBar() {
		titleTxt = (TextView) findViewById(R.id.title_txt);
		titleTxt.setText(getString(R.string.query_editor_txt));
		titleActionButton = (ImageButton) findViewById(R.id.title_action_image_btn);
		titleActionButton.setVisibility(View.GONE);
	}
	
	private void setDatabaseAdapter(String [] databaseNames) {
		ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_spinner_item, databaseNames);
		adapter.setDropDownViewResource(
				android.R.layout.simple_dropdown_item_1line);
		databaseSp.setAdapter(adapter);
		databaseSp.invalidate();
		
		// select the db with respect to db in shared preferences
		String dbNameFromPref = PreferencesManager.getString(getApplicationContext(), PREF_SESSION_DBNAME);
		for(int i=0; i<databaseNames.length; i++) {
			if(dbNameFromPref.toLowerCase().equalsIgnoreCase(databaseNames[i].toLowerCase())) {
				databaseSp.setSelection(i);
				break;
			}
		}
 		
	}

	private void setListeners() {
		goBtn.setOnClickListener(this);
		consoleBtn.setOnClickListener(this);
		tableBtn.setOnClickListener(this);
		clearBtn.setOnClickListener(this);
	}

	private void initUI() {
		query = (EditText) findViewById(R.id.query_editor_name_txt);
		goBtn = (Button) findViewById(R.id.query_editor_go_btn);
		outputTable = (TableLayout) findViewById(R.id.query_editor_output_table);
		outputTable.setBackgroundColor(Color.GRAY);
		databaseSp = (Spinner)findViewById(R.id.query_editor_database_sp);
		consoleBtn = (Button) findViewById(R.id.query_editor_tabs_console_btn);
		tableBtn = (Button) findViewById(R.id.query_editor_tabs_table_btn);
		consoleView = (LinearLayout) findViewById(R.id.query_editor_tabs_console_view);
		tableView = (LinearLayout) findViewById(R.id.query_editor_tabs_table_view);
		clearBtn = (Button)findViewById(R.id.query_editor_clr_btn);
	}
	
	public void setConsoleBtnTitle(String consoleBtnTitle) {
		consoleBtn.setText(consoleBtnTitle);
	}

	public void setTableBtnTitle(String tableBtnTitle) {
		tableBtn.setText(tableBtnTitle);
	}
	
	public void addViewToConsoleView(View child) {
		consoleView.addView(child);
	}

	public void addViewToTableView(View child) {
		tableView.addView(child);
	}
	
	@Override
	public void onClick(View view) {
		if(view == goBtn) {
		String queryStr = query.getText().toString();
		// check they query type and call respective web service
		if(queryStr.trim().toLowerCase().startsWith("show")) {
			executeQuery(new A2DbRunShowQueryRequest(), new RunShowQueryBuilder(), runShowQueryRequestHandler);	
		} else if(queryStr.trim().toLowerCase().startsWith("select") || queryStr.trim().toLowerCase().startsWith("desc")) {
			executeQuery(new A2DbRunSelectQueryRequest(), new RunSelectQueryBuilder(), runSelectQueryRequestHandler);
		} else {
			executeQuery(new A2DbRunQueryRequest(), new RunQueryBuilder(),  runQueryRequestHandler);
		}
		} else if(view == consoleBtn) {
			showConsoleTab();
		} else if(view == tableBtn) {
			showTableTab();
		}else if(view == clearBtn){
			query.setText("");
		}else {
			view.setBackgroundColor(Color.LTGRAY);
			for(int i=0; i<rows.size(); i++) {
				if(view == rows.get(i)) {
					TableRowItem rowItem = tableRows.get(i);
					tableRow = rowItem;
				}
			}
			Intent intent = new Intent(QueryEditorActivity.this, TableDataOperationActivity.class);
			startActivity(intent);
		}
	}
	
	private void showConsoleTab() {
		consoleBtn.setEnabled(false);
		consoleView.setVisibility(LinearLayout.VISIBLE);
		tableBtn.setEnabled(true);
		tableView.setVisibility(LinearLayout.GONE);
	}
	
	private void showTableTab() {
		consoleBtn.setEnabled(true);
		consoleView.setVisibility(LinearLayout.GONE);
		tableBtn.setEnabled(false);
		tableView.setVisibility(LinearLayout.VISIBLE);
	}

	private void executeQuery(BaseA2DbQueryRequest request, IA2DbWebRequestDelegate deligate, Handler handler) {
		request.encoded = true;
		request.host = 	PreferencesManager.getString(getApplicationContext(), PREF_SESSION_HOST);
		request.port =  PreferencesManager.getString(getApplicationContext(), PREF_SESSION_PORT);
		request.username = PreferencesManager.getString(getApplicationContext(), PREF_SESSION_USERNAME);
		request.password = PreferencesManager.getString(getApplicationContext(), PREF_SESSION_PASSWORD);
		request.dbname = databaseSp.getSelectedItem().toString(); 
		request.query = query.getText().toString(); 
		request.requestDelegate = deligate;
		new A2DbAsyncWebRequestTask(true, getApplicationContext(), handler, getProgressDialog()).execute(request);
	}

	private Handler runSelectQueryRequestHandler = new Handler() {
		@SuppressWarnings("unchecked")
		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			A2DbWebResult<SelectQueryResult> response = (A2DbWebResult<SelectQueryResult>) msg.obj;
			if(response == null) {
				showToast("Response is null");
			} else if(response.entity == null) {
				showToast("Server not found...");
			} else if(response.entity.result == null){
				displayOutput("", response.entity.error);
			} else {
				showTableTab();
				displayData(response.entity.result);
			}
		}
	};

	private Handler runShowQueryRequestHandler = new Handler() {
		@SuppressWarnings("unchecked")
		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			A2DbWebResult<ShowQueryResult> response = (A2DbWebResult<ShowQueryResult>) msg.obj;
			if(response == null) {
				showToast("Response is null");
			} else if(response.entity == null) {
				showToast("Server not found...");
			} else if(response.entity.result == null){
				displayOutput("", response.entity.error);
			} else {
				showTableTab();
				displayData(response.entity.result);
			}
		}
	};

	private Handler runQueryRequestHandler = new Handler() {
		@SuppressWarnings("unchecked")
		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			A2DbWebResult<QueryResult> response = (A2DbWebResult<QueryResult>) msg.obj;
			if(response == null) {
				showToast("Response is null");
			} else if(response.entity == null) {
				showToast("Server not found...");
			} else if(response.entity.result == null){
				displayOutput(response.entity.result, response.entity.error);
			} else {
				showConsoleTab();
				displayOutput(response.entity.result, response.entity.error);
			}
		}
	};	   
	
	public void startDatabaseRequestProcess() {
		A2DbRunShowQueryRequest request = new A2DbRunShowQueryRequest();
		request.encoded = true;
		request.host = 	PreferencesManager.getString(getApplicationContext(), PREF_SESSION_HOST);
		request.port =  PreferencesManager.getString(getApplicationContext(), PREF_SESSION_PORT);
		request.username = PreferencesManager.getString(getApplicationContext(), PREF_SESSION_USERNAME);
		request.password = PreferencesManager.getString(getApplicationContext(), PREF_SESSION_PASSWORD);
		request.dbname = PreferencesManager.getString(getApplicationContext(), PREF_SESSION_DBNAME);
		request.query = getQueryBuilder().getShowDatabasesQuery(); //PreferencesManager.getString(getApplicationContext(), PREF_SESSION_QUERY);
		request.requestDelegate = new RunShowQueryBuilder();
		new A2DbAsyncWebRequestTask(true, getApplicationContext(), runDatabaseQueryRequestHandler, getProgressDialog()).execute(request);
	}

	private Handler runDatabaseQueryRequestHandler = new Handler() {
		@SuppressWarnings("unchecked")
		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			A2DbWebResult<ShowQueryResult> response = (A2DbWebResult<ShowQueryResult>) msg.obj;
			if(response == null) {
				showToast("Response is null");
				QueryEditorActivity.this.finish();
			} else if(response.entity == null) {
				showToast("Server not found...");
				QueryEditorActivity.this.finish();
			} else if(response.entity.result == null){
				showToast(response.entity.error+"");
				QueryEditorActivity.this.finish();
			} else {
				String [][] data = response.entity.result.data;
				int rowLength = data[0].length;
				int columnHeight = data.length/rowLength;
				String [] databaseNames = new String[columnHeight];
				for(int i=0; i<columnHeight; i=i+rowLength) {
					databaseNames[i] = data[i][0];
				}
				setDatabaseAdapter(databaseNames);
			}
		}
	};	
	
	public void displayOutput(String output, String error) {
		TextView tv = new TextView(getApplicationContext());
		
		if(error != null && error.length() > 0) {
			tv.setText(error);
			tv.setTextColor(Color.RED);
		} else {
			tv.setText(output);
			tv.setTextColor(getResources().getColor(R.color.dark_green));
		}
		consoleView.addView(tv);
		showConsoleTab();
	}
	
	public void displayData(Table table) {
		// remove previous data
		outputTable.removeAllViews();
		rows = new ArrayList<View>();
		tableRows = new ArrayList<TableRowItem>();
		// add headers to the table layout		
		TableRow row = new TableRow(this);
		row.setBackgroundColor(Color.GRAY);
		row.setPadding(2, 2, 2, 2);
		for(int i=0; i<table.headers.length; i++) {
			row.addView(getTableHeaderTextView(this, table.headers[i].title));
		}
		// add header to the table layout
		outputTable.addView(row);

		if(table.data.length >= 1) {
			for(int i=0; i<table.data.length; i++) {
				row = new TableRow(this);
				row.setBackgroundColor(Color.GRAY);
				row.setPadding(2, 2, 2, 2);
				
				TableRowItem rowItem = new TableRowItem();
				List<TableDataItem> items = new ArrayList<TableDataItem>();
				for(int j=0; j<table.headers.length; j++) {
					row.addView(getTableDataTextView(this, table.data[i][j]));	
				}
				rowItem.items = items;
				tableRows.add(rowItem);
				row.setOnClickListener(this);
				outputTable.addView(row);
				rows.add(row);
			}
		}
		
	}
}